unit UVonXorCrypt;

interface

uses SysUtils, EncdDecd;

type
  TVonXorCrypt = class
  private
    Fkey: array [0 .. 255] of byte;
  public
    constructor Create(const Key: PByte; size: Integer);
    procedure Encrypt(const InData: PByte; OutData: PByte; size: Integer);
    procedure Decrypt(const InData: PByte; OutData: PByte; size: Integer);
    function EncryptString(const InStr: string): string;
    function DecryptString(const InStr: string): string;
    function EncryptAnsiString(const InStr: Ansistring): Ansistring;
    function DecryptAnsiString(const InStr: Ansistring): Ansistring;
  end;

implementation

{ TVonXorCrypt }

constructor TVonXorCrypt.Create(const Key: PByte; size: Integer);
const
  KEY_DEFAULT: array[0..255] of byte= (      //2044 = 256 * 7
    $09, $d0, $c4, $79, $28, $c8, $ff, $e0, $84, $aa, $6c, $39, $9d, $ad, $72, $87,
    $7d, $ff, $9b, $e3, $d4, $26, $83, $61, $c9, $6d, $a1, $d4, $79, $74, $cc, $93,
    $85, $d0, $58, $2e, $2a, $4b, $57, $05, $1c, $a1, $6a, $62, $c3, $bd, $27, $9d,
    $0f, $1f, $25, $e5, $51, $60, $37, $2f, $c6, $95, $c1, $fb, $4d, $7f, $f1, $e4,
    $ae, $5f, $6b, $f4, $0d, $72, $ee, $46, $ff, $23, $de, $8a, $b1, $cf, $8e, $83,
    $f1, $49, $02, $e2, $3e, $98, $1e, $42, $8b, $f5, $3e, $b6, $7f, $4b, $f8, $ac,
    $83, $63, $1f, $83, $25, $97, $02, $05, $76, $af, $e7, $84, $3a, $79, $31, $d4,
    $4f, $84, $64, $50, $5c, $64, $c3, $f6, $21, $0a, $5f, $18, $c6, $98, $6a, $26,
    $28, $f4, $e8, $26, $3a, $60, $a8, $1c, $d3, $40, $a6, $64, $7e, $a8, $20, $c4,
    $52, $66, $87, $c5, $7e, $dd, $d1, $2b, $32, $a1, $1d, $1d, $9c, $9e, $f0, $86,
    $80, $f6, $e8, $31, $ab, $6f, $04, $ad, $56, $fb, $9b, $53, $8b, $2e, $09, $5c,
    $b6, $85, $56, $ae, $d2, $25, $0b, $0d, $29, $4a, $77, $21, $e2, $1f, $b2, $53,
    $ae, $13, $67, $49, $e8, $2a, $ae, $86, $93, $36, $51, $04, $99, $40, $4a, $66,
    $78, $a7, $84, $dc, $b6, $9b, $a8, $4b, $04, $04, $67, $93, $23, $db, $5c, $1e,
    $46, $ca, $e1, $d6, $2f, $e2, $81, $34, $5a, $22, $39, $42, $18, $63, $cd, $5b,
    $c1, $90, $c6, $e3, $07, $df, $b8, $46, $6e, $b8, $88, $16, $2d, $0d, $cc, $4a);
var
  I: Integer;
begin
  for I := 0 to 255 do
    Fkey[I]:= KEY_DEFAULT[I] XOR Key[I mod size];
end;

procedure TVonXorCrypt.Decrypt(const InData: PByte; OutData: PByte; size: Integer);
var
  I, J: Integer;
  K: byte;
begin
  K:= InData[0];
  for I := 1 to size - 1 do begin
    OutData[I - 1]:= InData[I] XOR Fkey[(K + i) mod 256];
    OutData[I - 1]:= OutData[I - 1] XOR Fkey[(K + i - 1) mod 256];
  end;
end;

procedure TVonXorCrypt.Encrypt(const InData: PByte; OutData: PByte; size: Integer);
var
  I, J: Integer;
  K: byte;
begin
  K:= 0;
  for I := 0 to size - 1 do K:= K + InData[I];
  OutData[0]:= K;
  for I := 0 to size - 1 do begin
    OutData[I + 1]:= InData[I] XOR Fkey[(K + i) mod 256];
    OutData[I + 1]:= OutData[I + 1] XOR Fkey[(K + i + 1) mod 256];
  end;
end;

function TVonXorCrypt.DecryptString(const InStr: string): string;
var
  InData: TBytes;
  OutData: PByte;
begin
  InData:= DecodeBase64(InStr);
//  SetLength(Result, Length(InData) + 1);
//  FillChar(Result[1], Length(InData), #0);
  SetLength(Result, Length(InData) div SizeOf(char) + 1);
  FillChar(Result[1], Length(InData), #0);
  Decrypt(@InData[0], @Result[1], Length(InData));
end;

function TVonXorCrypt.EncryptString(const InStr: string): string;
var
  p: array of byte;
begin
  SetLength(P, Length(InStr) * SizeOf(char) + 1);
  Encrypt(@InStr[1], @P[0], Length(InStr) * SizeOf(char));
  Result:= EncodeBase64(P, Length(InStr) * SizeOf(char) + 1);
end;

function TVonXorCrypt.EncryptAnsiString(const InStr: Ansistring): Ansistring;
begin

end;

function TVonXorCrypt.DecryptAnsiString(const InStr: Ansistring): Ansistring;
var
  InData: TBytes;
  OutData: PByte;
begin
  InData:= DecodeBase64(InStr);
  SetLength(Result, Length(InData) + 1);
  FillChar(Result[1], Length(InData), #0);
  Decrypt(@InData[0], @Result[1], Length(InData));
end;

end.
